package com.swp.oa.sys.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.swp.oa.sys.dao.IAuthDao;
import com.swp.oa.sys.dao.IRoleAuthDao;
import com.swp.oa.sys.dto.domian.PermissionGroupItemsDto;
import com.swp.oa.sys.dto.domian.PermissionGroupDto;
import com.swp.oa.sys.dto.domian.PermissionItemDto;
import com.swp.oa.sys.dto.domian.PermissionValueDto;
import com.swp.oa.sys.dto.domian.RoleDto;
import com.swp.oa.sys.dto.page.EasyuiTreeNode;
import com.swp.oa.sys.pojo.Auth;
import com.swp.oa.sys.pojo.AuthExample;
import com.swp.oa.sys.pojo.Department;
import com.swp.oa.sys.pojo.DepartmentExample;
import com.swp.oa.sys.pojo.Role;
import com.swp.oa.sys.service.IAuthService;
import com.swp.oa.sys.util.JsonUtils;
import com.swp.oa.sys.util.Pager;
import com.swp.oa.util.DateUtil;
import com.swp.oa.util.UUIDGenerator;

@Service("authService")
public class AuthServiceImpl implements IAuthService{

	@Autowired
	private IAuthDao authDao;
	@Autowired
	private IRoleAuthDao roleAuthDao;

	@Override
	public boolean savePermissionGroup(PermissionGroupDto permissionGroup) {
		Auth auth = new Auth();
		auth.setAuthid(UUIDGenerator.getUUID());
		auth.setAuthname(permissionGroup.getName());
		auth.setCreatedate(new Date());
		auth.setDescription(permissionGroup.getDescription());
		auth.setUpdatedate(auth.getCreatedate());
		auth.setVersion(1);
		auth.setStatus("1");
		authDao.insertSelective(auth);
		return true;
	}
	@Override
	public boolean savePermissionItem(PermissionItemDto permissionItem) {
		Auth auth = new Auth();
		auth.setAuthid(UUIDGenerator.getUUID());
		auth.setParentauthid(permissionItem.getPermissionGroupId());
		auth.setAuthname(permissionItem.getDisplayName());
		auth.setCode(permissionItem.getCode());
		auth.setCreatedate(new Date());
		auth.setUpdatedate(auth.getCreatedate());
		auth.setVersion(1);
		auth.setStatus("1");
		authDao.insertSelective(auth);
		return true;
	}	

	@Override
	public boolean deleteByPrimaryKey(String authid) {
		roleAuthDao.deleteByAuthId(authid);
		authDao.deleteByPrimaryKey(authid);		
		return true;
	}
	@Override
	public boolean delete(String[] permissionGroupIdArray) {
		AuthExample example = new AuthExample();
		List<String> ids = new ArrayList<String>();
		for (String groupId : permissionGroupIdArray) {
			ids.add(groupId);
			example.or().andParentauthidEqualTo(groupId);
			List<Auth> auths = authDao.selectByExample(example);
			if (auths != null){
				for (Auth auth : auths) {
					ids.add(auth.getAuthid());
					roleAuthDao.deleteByAuthId(auth.getAuthid());

				}
			}
		}
		example.or().andAuthidIn(ids);
		int flag = authDao.deleteByExample(example);
		if(flag > 0){
			return true;			
		}
		return false;
	}
	@Override
	public boolean update(PermissionGroupDto permissionGroup) {
		Auth auth = new Auth();
		auth.setAuthid(permissionGroup.getId());
		auth.setAuthname(permissionGroup.getName());
		auth.setDescription(permissionGroup.getDescription());
		auth.setUpdatedate(new Date());
		authDao.updateByPrimaryKeySelective(auth);
		return true ;
	}
	@Override
	public boolean updatePermissionItem(PermissionItemDto permissionItem) {
		Auth auth = new Auth();
		auth.setAuthid(permissionItem.getId());
		auth.setAuthname(permissionItem.getDisplayName());
		auth.setCode(permissionItem.getCode());
		auth.setUpdatedate(new Date());
		authDao.updateByPrimaryKeySelective(auth);
		return true;
	}
	@Override
	public List<PermissionGroupDto> getAllPermissionGroupList() {
		AuthExample example = new AuthExample();
		example.or().andParentauthidIsNull();
		List<Auth> list = authDao.selectByExampleWithBLOBs(example);
		List<PermissionGroupDto> groups = new ArrayList<PermissionGroupDto>();
		if (list != null){
			PermissionGroupDto group = null;
			for (Auth auth : list) {
				group = new PermissionGroupDto();
				group.setId(auth.getAuthid());
				group.setName(auth.getAuthname());
				group.setDescription(auth.getDescription());
				group.setCreateDate(DateUtil.dateFormat(auth.getCreatedate()));
				groups.add(group);
			}
			return groups;			
		}
		return null;
	}	
	@Override
	public Pager getAllPermissionGroupList(int pageIndex, int pageSize) {
		PageHelper.startPage(pageIndex,pageSize); 
		AuthExample example = new AuthExample();
		example.or().andParentauthidIsNull();
		example.setOrderByClause("CreateDate");
		List<Auth> list = authDao.selectByExampleWithBLOBs(example);
		PageInfo page = new PageInfo(list);
		if (list != null && list.size() > 0){
			List<PermissionGroupDto> groups = new ArrayList<PermissionGroupDto>();
			PermissionGroupDto group = null;
			for (Auth auth : list) {
				group = new PermissionGroupDto();
				group.setId(auth.getAuthid());
				group.setName(auth.getAuthname());
				group.setDescription(auth.getDescription());
				group.setCreateDate(DateUtil.dateFormat(auth.getCreatedate()));
				groups.add(group);
			}
			Pager pager = new Pager(pageIndex, pageSize, page.getTotal(), groups);
			return pager;			
		}
		return null;
	}
	@Override
	public List<PermissionItemDto> getPermissionItemsByPermissionGroupId(
			String permissionGroupId) {
		AuthExample example = new AuthExample();
		example.setOrderByClause("Code");
		example.or().andParentauthidEqualTo(permissionGroupId);
		List<Auth> list = authDao.selectByExampleWithBLOBs(example);
		List<PermissionItemDto> permissions = new ArrayList<PermissionItemDto>();
		if(list != null && list.size() > 0){
			PermissionItemDto permission = null;
			for (Auth auth : list) {
				permission = new PermissionItemDto(); 
				permission.setId(auth.getAuthid());
				permission.setDisplayName(auth.getAuthname());
				permission.setCode(auth.getCode());
				permission.setCreateDate(DateUtil.dateFormat(auth.getCreatedate()));
				permission.setPermissionGroupId(permissionGroupId);
				permissions.add(permission);
			}
		}
		return permissions;			
	}

	@Override
	public Auth getAuthByPrimaryKey(String authId) {
		return authDao.selectByPrimaryKey(authId);
	}
	@SuppressWarnings("unused")
	@Override
	public String existPermissionItem(PermissionItemDto permissionItem) {
		AuthExample example = new AuthExample();
		List<Auth> auth_codes = null;
		List<Auth> auth_names = null;
		if (permissionItem.getCode() != null){
			example.or().andCodeEqualTo(permissionItem.getCode());
			auth_codes = authDao.selectByExample(example);			
		}
		if (permissionItem.getDisplayName() != null){
			example.or().andAuthnameEqualTo(permissionItem.getDisplayName());
			auth_names = authDao.selectByExample(example);			
		}
		if(auth_codes != null && auth_codes.size() > 0 && auth_names != null && auth_names.size() > 0){
			return "权限代码与显示名称已存在";
		}
		if(auth_codes != null && auth_codes.size() > 0){
			return "权限代码已存在";
		}
		if(auth_names != null && auth_names.size() > 0){
			return "显示名称已存在";
		}
		return null;
	}
	@SuppressWarnings("unused")
	@Override
	public String existEditPermissionItem(PermissionItemDto permissionItem) {
		AuthExample example = new AuthExample();
		List<Auth> auth_codes = null;
		List<Auth> auth_names = null;
		Auth auth = authDao.selectByPrimaryKey(permissionItem.getId());
		
		if (permissionItem.getCode() != null){
			if(!auth.getCode().equals(permissionItem.getCode())){
				example.or().andCodeEqualTo(permissionItem.getCode());
				auth_codes = authDao.selectByExample(example);			
			}
		}
		if (permissionItem.getDisplayName() != null){
			if(!auth.getAuthname().equals(permissionItem.getDisplayName())){
				example.or().andAuthnameEqualTo(permissionItem.getDisplayName());
				auth_names = authDao.selectByExample(example);							
			}
		}
		if(auth_codes != null && auth_codes.size() > 0 && auth_names != null && auth_names.size() > 0){
			return "权限代码与显示名称已存在";
		}
		if(auth_codes != null && auth_codes.size() > 0){
			return "权限代码已存在";
		}
		if(auth_names != null && auth_names.size() > 0){
			return "显示名称已存在";
		}
		return null;
	}
	@Override
	public List<PermissionGroupItemsDto> getPermissionGroupItems() {
		List<PermissionGroupItemsDto> list = new ArrayList<PermissionGroupItemsDto>();
		List<PermissionGroupDto> groups = this.getAllPermissionGroupList();
		PermissionGroupItemsDto groupItems = null;
		if(groups != null){
			for (PermissionGroupDto group : groups) {
				groupItems = new PermissionGroupItemsDto();
				groupItems.setGroup(group);
				List<PermissionItemDto> permissions = this.getPermissionItemsByPermissionGroupId(group.getId());
				if(permissions != null){
					groupItems.setItems(permissions);					
				}
				list.add(groupItems);
			}
			return list;
		}
		
		return null;
	}
	private PermissionGroupDto pojoToPermissionGroupModel(Auth auth){
		PermissionGroupDto group = new PermissionGroupDto();
			group.setId(auth.getAuthid());
			group.setName(auth.getAuthname());
			group.setDescription(auth.getDescription());
			group.setCreateDate(DateUtil.dateFormat(auth.getCreatedate()));
		return group;
	}
	private PermissionItemDto pojoToPermissionItemModel(Auth auth){
		PermissionItemDto permission = new PermissionItemDto(); 
		permission.setId(auth.getAuthid());
		permission.setDisplayName(auth.getAuthname());
		permission.setCode(auth.getCode());
		permission.setCreateDate(DateUtil.dateFormat(auth.getCreatedate()));
		permission.setPermissionGroupId(auth.getParentauthid());
		return permission;
	}

	@Override
	public Map<String, PermissionValueDto> ToPermissionDictionary(
			RoleDto role) {
		// 防止为空时反序列化出错
		String permissionJsonData = "{}";
		if (role != null
				&& StringUtils.isNotEmpty(role.getPermissionJsonData())) {
			permissionJsonData = role.getPermissionJsonData();
		}
		Map<String, PermissionValueDto> permissions = JsonUtils
				.json2GenericObject(permissionJsonData,
						new TypeReference<Map<String, PermissionValueDto>>() {
						});
		return permissions;
	}
	@Override
	public List<EasyuiTreeNode> getTree(String roleId) {
		Role role = roleAuthDao.selectAuthsByRoleId(roleId);
		Set<String> roleAuthIds = new HashSet<String>();
		if(role != null){
			List<Auth> roleAuths = role.getAuths();
			for (Auth a : roleAuths) {
				roleAuthIds.add(a.getAuthid());
			}
		}
		List<EasyuiTreeNode> nodes = new ArrayList<EasyuiTreeNode>();
		AuthExample example = new AuthExample();
		example.or().andParentauthidIsNull();
		example.setOrderByClause("CreateDate");
		List<Auth> list = authDao.selectByExampleWithBLOBs(example);
		if(list != null && list.size() > 0){
			EasyuiTreeNode tree = null;
			if(roleAuthIds != null && roleAuthIds.size() > 0){
				for (Auth group : list) {
					tree = this.toTree(group,roleAuthIds);
					if(tree != null){
						nodes.add(tree);						
					}
				}				
			}else{
				for (Auth group : list) {
					tree = this.toTree(group);
					if(tree != null){
						nodes.add(tree);						
					}
				}	
			}
			return nodes;
		}
		return null;
	}
	/**
	 * 递归辅助函数
	 * @return
	 */
	private EasyuiTreeNode toTree(Auth group, Set<String> roleAuthIds) {
		AuthExample example = new AuthExample();
		example.or().andParentauthidEqualTo(group.getAuthid());
		example.setOrderByClause("Code");
		List<Auth> list = authDao.selectByExampleWithBLOBs(example);
		if (list != null && list.size() > 0) {
			EasyuiTreeNode node = new EasyuiTreeNode();
			node.setId(group.getAuthid());
			node.setText(group.getAuthname());
			List<EasyuiTreeNode> children = new ArrayList<EasyuiTreeNode>();
			EasyuiTreeNode node_children = null;
//			int flag = 0;
			for (Auth auth_children : list) {
				node_children = new EasyuiTreeNode();
				node_children.setId(auth_children.getAuthid());
				node_children.setText(auth_children.getAuthname());
				if(roleAuthIds.contains(auth_children.getAuthid())){
					node_children.setChecked(true);
//					flag++;
				}
				children.add(node_children);
			}
//			if(flag + 1 == list.size()){
//				node.setChecked(true);
//			}
			node.setChildren(children);
			return node;
		}
		return null;
	}
	private EasyuiTreeNode toTree(Auth group) {
		
		AuthExample example = new AuthExample();
		example.or().andParentauthidEqualTo(group.getAuthid());
		List<Auth> list = authDao.selectByExampleWithBLOBs(example);
		if (list != null && list.size() > 0) {
			EasyuiTreeNode node = new EasyuiTreeNode();
			node.setId(group.getAuthid());
			node.setText(group.getAuthname());
			List<EasyuiTreeNode> children = new ArrayList<EasyuiTreeNode>();
			EasyuiTreeNode node_children = null;
			for (Auth auth_children : list) {
				node_children = new EasyuiTreeNode();
				node_children.setId(auth_children.getAuthid());
				node_children.setText(auth_children.getAuthname());
				children.add(node_children);
			}
			node.setChildren(children);
			return node;
		}
		return null;
	}

}
